#ifndef XDUMPER2_H
#define XDUMPER2_H

#include "controller/hidapi.h"
#include "memory.h"
#include "string.h"

/* error code */
#define ERR_OK				(0x00)
#define ERR_CRC				(0x01)
#define ERR_IO				(0x02)
#define ERR_FMT				(0x03)
#define ERR_FSIZE			(0x04)
#define ERR_TIMEOUT			(0x05)
#define ERR_ERASE			(0x06)
#define ERR_WRITE			(0x07)
#define ERR_CMD				(0x08)
#define ERR_ATOM            (0x09)
#define ERR_CONN			(0x0D)	//m
#define ERR_NODEV			(0x0B)
#define ERR_HWLOW			(0x0C)
#define ERR_INVAL			(0x10)	//m
#define ERR_SEND			(0x11)	//m
#define ERR_RECV			(0x12)	//m

#define CMD_START			(0x01)			/* start transfer */
#define CMD_DATA			(0x02)			/* data packet */
#define CMD_ABT				(0x03)			/* master -> slaver abort */
#define CMD_END				(0x04)			/* packet send complete */
#define	CMD_SET_SN			(0x05)			/* setting Serial Number */
#define CMD_PING			(0x06)			/* Ping */
#define CMD_SET_PEM			(0x07)			/* extended command */

#define CMD_PUT_FILE_START  (0x08)
#define CMD_PUT_FILE_DATA   (0x09)
#define CMD_PUT_FILE_END    (0x0A)
#define CMD_GET_FILE_START  (0x0B)
#define CMD_GET_FILE_DATA   (0x0C)
#define CMD_GET_FILE_END    (0x0D)
#define CMD_DEL_FILE        (0x0E)
#define CMD_LST_FILE_START  (0x0F)
#define CMD_LST_FILE_DATA   (0x10)
#define CMD_LST_FILE_END    (0x11)
#define CMD_ITEM_OPT_START  (0x12)
#define CMD_ITEM_OPT_ADD    (0x13)
#define CMD_ITEM_OPT_DEL    (0x14)
#define CMD_ITEM_OPT_MOD    (0x15)
#define CMD_ITEM_OPT_GET    (0x16)
#define CMD_ITEM_OPT_END    (0x17)
#define CMD_ERASE_FLASH     (0x18)
#define CMD_MV_FILE			(0x19)
#define CMD_UPD				(0x1A)
#define CMD_GET_FILECNT     (0x1B)
#define CMD_GET_WORKMODE    (0x1C)
#define CMD_GET_FORMATINFO	(0x1D)
#define CMD_GET_LARGE_START	(0x1E)
#define CMD_GET_LARGE_DATA	(0x1F)
#define CMD_GET_LARGE_END	(0x20)

#define DATALEN				(1152-16)		/* MAX DATA LEN */
#define PACK_SIZE           (64)
#define ACKDATALEN          (640-5)

#define ACKPACK_LARGE_TOP	(5)
#define ACKDATALEN_LARGE    (640)

#define ACKCMD_OK           (0x00)			/* received packet OK */
#define ACKCMD_ERR          (0xFF)			/* received packet error ,error no is*/

#define ACKCMDMAGIC			(0xCA)
#define CMDMAGIC			(0xAC)
#define PKT_TYPE_APP		(0x00)
#define PKT_TYPE_SRC		(0x01)
#define BAUD_RATE			(256000)

#define	DEV_VID             (0xC25A)
#define DEV_PID             (0x330E)

#pragma pack(push,1)
typedef struct _ackpack{
    unsigned char	ack_magic;			/* magic */
    unsigned char	ack_cmd ;			/* ackcmd */
    unsigned short	ack_pknr;			/* packet nr */
    char            ack_buf[ACKDATALEN];/* buffer */
    unsigned char	ack_crc;			/* ack cmd crc */
}ACKPACK;


typedef struct _largeFileInfo{
    char fileName[20];
    int multiple;
}largeFileInfo;

typedef struct _ackpack_large{
    unsigned char	ack_magic;			/* magic */
    unsigned char	ack_cmd ;			/* ackcmd */
    unsigned short	ack_pknr;			/* packet nr */
    unsigned char	ack_crc;			/* ack cmd crc */
    char            ack_buf[1];          /* buffer */
}ACKPACK_LARGE;

typedef  struct _pack{
    unsigned char	magic;				/* magic */
    unsigned char   cmd;				/* cmd */
    unsigned short  pknr;				/* pack nr */
    unsigned short	pkt_type;			/* packet type */
    unsigned char	padding[9];         /* padding data */
    char            dat[DATALEN];		/* dat */
    unsigned char   crc;				/* dat crc */
}PACK;


typedef struct _devinfo {
    unsigned char hw_type_major;      /* major hard ware type :
                                         * 00 : 6632
                                         * 01 : 6621
                                         * 02 : 6611
                                         * 03 : 6631
                                         */
    unsigned char hw_type_minor;      /* minor hard ware type
                                         * for now ,DON'T Care
                                         */
    unsigned short  bldr_ver;           /* boot loader version */
    unsigned char   locked;             /* locked bit */
    char            sn[13];            /* serial number */
    char            hw_ver[2];			/* hardware version */
    unsigned        app_ver;            /* application version */
    unsigned        lang_ver;           /* language version */
    unsigned short	fs_ver;				/* agreement version*/
    char			FormatInfo[64];		/* FormatInfo*/
}DEVINFO;
#pragma pack (pop)

#define	CB_CMD_START		(0x00)				/* callback start */
#define CB_CMD_DOING		(0x01)				/* callback calling */
#define CB_CMD_END			(0x02)				/* callback end */

typedef	int (*call_back)(int cmd,int cur,int total,void *arglist);
typedef int	(__stdcall *item_proc)(int cmd,int idx,const char *item,void *arglist);

class xDumper2
{
public:
    hid_device *handle;
    DEVINFO	deviceInfo;

    xDumper2(hid_device *handle = NULL)
    {
        this->handle = handle;
    }

    xDumper2(const xDumper2& A)
    {
        *this = A;
    }

    ~xDumper2();
    int send_buffer(unsigned char *buffer, int size, unsigned timeout);
    int recv_buffer(unsigned char *buffer, int size, unsigned timeout);
    int enterXdumper(unsigned timeout = 800);
    int connectDevice();
    int disconnectDevice();
    int pingDevice();
    int getFileList(item_proc proc);
    int getFile(const char *remote_path, const char *local_path, call_back cb,int *quit, void *arglist);
    int getFileLarge(const char *remote_path, const char *local_path, int pkt_multiple, call_back cb,int *quit, void *arglist);

private:
};

#endif // XDUMPER2_H
